package mathive.server;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.google.appengine.api.datastore.Key;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import mathive.client.ClientTest;
import mathive.client.ClientGamesData;
import mathive.client.TestService;
import mathive.server.persistant.GamesData;
import mathive.server.persistant.SessionID;
import mathive.server.persistant.Test;
import mathive.server.persistant.User;

@SuppressWarnings("serial")
public class TestServiceImpl extends RemoteServiceServlet implements TestService {
	
	public boolean createTest(String session, ClientTest clientTest) {
		System.out.println("In servlet");
		PersistenceManager pm = PMF.getPersistenceManager();
		Key userKey = getSession(session, pm).getUserKey();
		User user = pm.getObjectById(User.class, userKey);
		
		if (user.getUsertype() == User.TEST_USER || user.getUsertype() == User.ADMIN || user.getUsertype() == User.USER) {
			Test existingTest = getTest(clientTest.getName(), pm);
			
			if (existingTest == null) {
				List<GamesData> gamesData = Arrays.asList((convertClientGamesDataToGamesData(clientTest.getGames())));
				
				Test test = new Test(clientTest.getName(), clientTest.getScore(), gamesData, userKey);
				pm.makePersistent(test);
				
				return true;
			}
		}
		return false;
	}

	public boolean deleteTest(String name){
		
		PersistenceManager pm = PMF.getPersistenceManager();
		
		String query = "select from " + Test.class.getName()+ " where name == '" + name + "'";
		List<Test> tests = (List<Test>) pm.newQuery(query).execute();
		Test test = tests.get(0);

		try {
			pm.deletePersistent(test);
		} finally {
			pm.close();
		}
		return true;
	}
	
	public String[] getAvaibleTests() {
		PersistenceManager pm = PMF.getPersistenceManager();
		
		Query query = pm.newQuery(Test.class);
	    
		List<Test> list = (List<Test>)query.execute();
		Iterator<Test> iterator = list.iterator();
		
		SimpleDateFormat formatter;

		formatter = new SimpleDateFormat("d MMMMM yyyy");
		
		String[] testString = new String[list.size()];
		int i = 0;
		while(iterator.hasNext()) {
			Test test = iterator.next();
			User user = pm.getObjectById(User.class, test.getCreator());
			testString[i] = test.getName()+ " "
					+ user.getUsername() + " "
					+ formatter.format(test.getDateCreated()) + " "
					+ test.nrOfGames();
			i++;
		}
	    
	    return testString;
	}
	
	public ClientTest getATest(String testname) {
		PersistenceManager pm = PMF.getPersistenceManager();
		
		Test test = getTest(testname, pm);
		
		ClientGamesData[] clientGames = convertGamesDataToClientGamesData(test.getGames());
		
		return new ClientTest(test.getName(), test.getScore(), clientGames, test.getDateCreated());
	}
	
	private GamesData[] convertClientGamesDataToGamesData(ClientGamesData[] clientGamesData) {
		GamesData[] gamesData = new GamesData[clientGamesData.length];
		for (int i = 0; i < clientGamesData.length; i++) {
			ClientGamesData clientData = clientGamesData[i];
			GamesData data = new GamesData(
					clientData.getId(),
					clientData.getType(),
					clientData.getDifficulty());
			gamesData[i] = data;
		}
		return gamesData;
	}
	
	private ClientGamesData[] convertGamesDataToClientGamesData(List<GamesData> gamesList) {
		Iterator<GamesData> iterator = gamesList.iterator();
		
		ClientGamesData[] clientGames = new ClientGamesData[gamesList.size()];
		int i = 0;
		while(iterator.hasNext()) {
			GamesData gameData = iterator.next();
			clientGames[i] = new ClientGamesData(
					gameData.getType(),
					gameData.getDifficulty(),
					gameData.getId());
			i++;
		}
		return clientGames;
	}
	
	private Test getTest(String testname, PersistenceManager pm) {		
		Query query = pm.newQuery(Test.class);
		query.setUnique(true);
		query.declareParameters("String param");
	    query.setFilter("name == param");
	    
	    return (Test)query.execute(testname);
	}
	
	private SessionID getSession(String session, PersistenceManager pm) {		
		Query query = pm.newQuery(SessionID.class);
		query.setUnique(true);
		query.declareParameters("String param");
	    query.setFilter("sessionID == param");
	    
	    return (SessionID)query.execute(session);
	}
	
	public String addStatistics(String name, String session, String stats){
		PersistenceManager pm = PMF.getPersistenceManager();
		
		Key userKey = getSession(session, pm).getUserKey();
		User user = pm.getObjectById(User.class, userKey);
		Test test = getTest(name, pm);

		test.addStatistics(user.getUsername(), stats);
		
		pm.close();
		
		return "ok";
	}

	@Override
	public String[] getMyTests(String session) {
		PersistenceManager pm = PMF.getPersistenceManager();

		String query = "select from " + Test.class.getName();// + 
//			" where creator == '" + getSession(session, pm).getUserKey() + "'";
		List<Test> tests = (List<Test>) pm.newQuery(query).execute();
		
		Iterator<Test> iterator = tests.iterator();
		
		System.out.println(getSession(session, pm).getUserKey());
		
		SimpleDateFormat formatter;

		formatter = new SimpleDateFormat("d MMMMM yyyy");
		
		Vector<String> testString = new Vector<String>();
		while(iterator.hasNext()) {
			Test test = iterator.next();
			User user = pm.getObjectById(User.class, getSession(session, pm).getUserKey());
			if (user.getKey().equals(test.getCreator())) {
				testString.add(test.getName()+ " "
						+ user.getUsername() + " "
						+ formatter.format(test.getDateCreated()) + " "
						+ test.nrOfGames());
			}
		}
		
		String[] s = new String[testString.size()];
		for (int i = 0; i < s.length; i++) {
			s[i] = testString.elementAt(i);
		}
		
	    return s;
	}

	@Override
	public String[] getStatistics(String name) {
		PersistenceManager pm = PMF.getPersistenceManager();

		String query = "select from " + Test.class.getName()+ " where name == '" + name + "'";
		List<Test> tests = (List<Test>) pm.newQuery(query).execute();
		Test test = tests.get(0);
		
		List<String> stats = (List<String>)test.getStatistics();

		String[] statsString = new String[stats.size()];
		
//		SimpleDateFormat formatter;
//
		Iterator<String> iterator = stats.iterator();
//
//		formatter = new SimpleDateFormat("d MMMMM yyyy");
//		
		int i = 0;
		while(iterator.hasNext()) {
			String stat = iterator.next();
//			User user = pm.getObjectById(User.class, test.getCreator());
			statsString[i] = stat;
			i++;
		}
		System.out.println("In TestServiceImpl: " + statsString.toString());
		
//		statsString = stats.toArray(Object[] a);
	    
	    return statsString;
	}

}
